package kioschool.basic.model 
{
	import kioschool.basic.view.View;

	/**
	 * Граф, инкапсулирует связи между вершинами и ребрами
	 * 
	 * @author Akimushkin Vasiliy
	 */
	public class Graph 
	{
		/**
		 * Список вершин
		 */
		private var _vertexes:Array = [];
		
		/**
		 * Список ребер
		 */
		private var _edges:Array = [];
		
		
		/**
		 * Представление
		 */
		private var _view:View;
		
		/**
		 * Конструктор
		 */
		public function Graph()	{
			
		}
		
		/**
		 * Получает список вершин
		 */
		public function get vertexes():Array{
			return _vertexes;
		}

		/**
		 * Получает список ребер
		 */
		public function get edges():Array{
			return _edges;
		}
		
		/**
		 * Устанавливает список ребер
		 */
		public function set edges(ar:Array):void{
			_edges=ar;
		}
		
		/**
		 * Получает представление
		 */
		public function get view():View{
			return _view;
		}
		
		/**
		 * Устанавливает представление
		 */
		public function set view(value:View):void{
			_view = value;
		}
		
		/**
		 * Получает ребро по двум вершинам
		 */ 
		public function getEdge(v1:Vertex, v2:Vertex):Edge {
			for (var i:int; i < edges.length; i++ ) {
				var  edge:Edge = edges[i];
				if (edge.source.id == v1.id && edge.target.id == v2.id)
					return edge;
				if (edge.source.id == v2.id && edge.target.id == v1.id)
					return edge;
			}
			return null;
		}
		
		/**
		 * Получает количество инцидентный ребер
		 */ 
		public function getIncidentEdges(v1:Vertex):int {
			var sum:int=0;
			for (var i:int; i < edges.length; i++ ) {
				var  edge:Edge = edges[i];
				if (edge.source.id == v1.id || edge.target.id == v1.id)
					sum++;
			}
			return sum;
		}
		
		/**
		 * Проверяет, существует ли путь из v1 в v2
		 */ 
		public function isPath(v1:Vertex, v2:Vertex):Boolean{
			for each (var vertex:Vertex in vertexes){
				vertex.labeled = false;
			}
			label(v1);
			return v2.labeled;
		}
		
		private function label(vertex:Vertex):void{
			vertex.labeled=true;
			for each (var edge:Edge in edges){
				if(edge.source==vertex && !edge.target.labeled){
					label(edge.target);
				}
				else if(edge.target==vertex && !edge.source.labeled){
					label(edge.source);
				}
			}
		}
		
		public function removeEdge(edge:Edge):void{
			var ar:Array = edges;
			edges = new Array();
			for each(var e:Edge in ar){
				if(e != edge)
					edges.push(e);
			}
		}
	}

}